package net.sf.midollo.net.protocol.multitunnel.client;

import java.io.IOException;

import net.sf.midollo.io.IOStream;
import net.sf.midollo.io.IOStreamFactory;
import net.sf.midollo.net.protocol.Protocol;
import net.sf.midollo.net.protocol.ProtocolFactory;
import net.sf.midollo.net.protocol.multitunnel.MultiTunnelManager;
import net.sf.midollo.net.protocol.multitunnel.MultiTunnelSession;
import net.sf.midollo.utils.Utils;

public class MultiTunnelClientFactory extends MultiTunnelManager implements ProtocolFactory {

  protected final IOStreamFactory ioTunnelFactory;
  protected final int requestBufSize;
  protected int lastSessionId;

  public MultiTunnelClientFactory(IOStreamFactory ioTunnelFactory, int requestBufSize) {
    this.ioTunnelFactory = ioTunnelFactory;
    this.requestBufSize = requestBufSize;
  }

  public Protocol connect(IOStream ioRequest) throws IOException {
    Utils.log("connect client");
    synchronized (this.lock) {
      if (this.ioTunnel == null) {
        Utils.log("open tunnel");
        this.lastSessionId = 0;
        IOStream ioTunnel = this.ioTunnelFactory.open();
        connectTunnelManager(ioTunnel, false);
      }
      return createClientSession(ioRequest, this.requestBufSize);
    }
  }

  protected void disconnect(MultiTunnelClient client) throws IOException {
    synchronized (this.lock) {
      removeSession(client.getSessionId(), true);
    }
  }

  protected MultiTunnelClient createClientSession(IOStream ioRequest, int bufSize) throws IOException {
    int sessionId = ++this.lastSessionId;
    MultiTunnelClient client = new MultiTunnelClient(this, sessionId, ioRequest, bufSize);
    addSession(client);
    return client;
  }

  protected MultiTunnelSession createSession(int sessionId) throws IOException {
    return null;
  }
}
